#include <iostream>
#include <QtCore\QDebug>
#include <QtGui\QMouseEvent>
#include <OgreRenderWindow.h>
#include <OgreRoot.h>
#include "OgreWidget.h"


OgreWidget::OgreWidget(QWidget* parent)
  : QWidget(parent)
{
  setAttribute(Qt::WA_PaintOnScreen, true);
  mTranslateVec = Ogre::Vector3::ZERO;
  mMoveSpeed = 100.0f;
  mRotX = 0;
  mRotY = 0;
}

OgreWidget::~OgreWidget(void)
{
}

bool OgreWidget::setup(void)
{
  bool success = OgreApplication::setup();
  if (success)
    emit setupComplete();
  return success;
}

void OgreWidget::mousePressEvent(QMouseEvent* e)
{
  if (e->button() == Qt::LeftButton)
  {
    mLastMousePos = e->pos();
  }
}

void OgreWidget::mouseMoveEvent(QMouseEvent* e)
{
  QPoint diff = e->pos() - mLastMousePos;
  mLastMousePos = e->pos();

  // Left button only
  if (e->buttons() == Qt::LeftButton)
  {
    mRotX = Ogre::Degree(-diff.x()*0.13);
    mRotY = Ogre::Degree(-diff.y()*0.13);

    mpCamera->yaw(mRotX);
		mpCamera->pitch(mRotY);
  }
}

void OgreWidget::mouseReleaseEvent(QMouseEvent* e)
{
}

void OgreWidget::keyPressEvent(QKeyEvent* e)
{
  if      (e->key() == Qt::Key_W) mTranslateVec.z = -1;
  else if (e->key() == Qt::Key_S) mTranslateVec.z =  1;
  if      (e->key() == Qt::Key_A) mTranslateVec.x = -1;
  else if (e->key() == Qt::Key_D) mTranslateVec.x =  1;
}

void OgreWidget::keyReleaseEvent(QKeyEvent* e)
{
  if (e->key() == Qt::Key_W || e->key() == Qt::Key_S) mTranslateVec.z = 0;
  if (e->key() == Qt::Key_A || e->key() == Qt::Key_D) mTranslateVec.x = 0;
}

void OgreWidget::timerEvent(QTimerEvent* e)
{
  renderOneFrame();
}

void OgreWidget::resizeEvent(QResizeEvent*)
{
}

void OgreWidget::update(float timeSinceLastUpdate)
{
  moveCamera(mTranslateVec*timeSinceLastUpdate);
}

bool OgreWidget::configure(void)
{
  // Show the configuration dialog and initialise the system
  if (mpRoot->restoreConfig() || mpRoot->showConfigDialog())
  {
    mpRoot->initialise(false);

    Ogre::NameValuePairList params;
    params["externalWindowHandle"] = Ogre::StringConverter::toString((unsigned int)WindowFromDC(getDC()));
    params["FSAA"] = 2;
    int w = width();
    int h = height();
    mpWindow = mpRoot->createRenderWindow("OgreWidget", w, h, false, &params);

    return true;
  }

  return false;
}

void OgreWidget::moveCamera(const Ogre::Vector3& translate)
{
  mpCamera->moveRelative(translate*mMoveSpeed);
}

void OgreWidget::rotateCamera(float rx, float ry, float rz)
{
  mpCamera->yaw(Ogre::Degree(ry));
  mpCamera->pitch(Ogre::Degree(rx));
  mpCamera->roll(Ogre::Degree(rz));
}
